/**
 * 
 */
package com.nari.basic.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.nari.basic.dao.IMenuDao;
import com.nari.basic.dao.IRoleMenuDao;
import com.nari.basic.model.IMenu;
import com.nari.basic.model.IRoleMenu;
import com.nari.coreframe.service.GenericServiceImpl;
import com.nari.platform.components.dhtmltree.DhtmlTreeNode;
import com.nari.platform.components.dhtmltree.TreeUserData;
import com.nari.platform.model.ResponseMsg;

/**
 * 
 * @author Xiaopeng
 * @date 2013-7-18
 */
public class MenuServiceImpl extends GenericServiceImpl<IMenu, String> 
		implements IMenuService {
	private String pMenuIcon;
	private String cMenuIcon;
	private IRoleMenuDao iRoleMenuDao;
	
	/**
	 * 查询系统所有菜单
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<IMenu> queryAllMenusInOrder() throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		return iMenuDao.queryAllMenusInOrder();
	}

	/**
	 * 通过角色唯一识别码查询其对应的菜单列表
	 * @param roleUIDs 角色唯一识别码
	 *   格式：XXX,XXX,XXX
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-22
	 */
	public List<IMenu> queryUserMenuByRoleUIDs(String roleUIDs) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		return iMenuDao.queryUserMenuByRoleUIDs(roleUIDs);
	}
	
	/**
	 * 查询菜单根节点，并过滤出权限菜单
	 * @param authorityMenuList 权限菜单，默认无权限过滤
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<IMenu> queryFirstLevelMenu(List<IMenu> authorityMenuList) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		return iMenuDao.queryFirstLevelMenu(authorityMenuList);
	}
	
	/**
	 * 根据父菜单ID查询子菜单节点，并过滤出权限菜单（需要情况下）
	 * @param pMenuID 若父菜单不存在，则查询根节点
	 * @param authorityMenuList 权限菜单，默认无权限过滤
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<IMenu> queryChildMenuByParent(String pMenuID, List<IMenu> authorityMenuList) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		return iMenuDao.queryChildMenuByParent(pMenuID, authorityMenuList);
	}
	
	/**
	 * 将菜单列表转化为树节点
	 * @param menuList
	 * @param ifLeafMenu 标识菜单节点是否为叶子节点，默认非叶子节点
	 * @return
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<DhtmlTreeNode> formatMenuListToTreeNodes(List<IMenu> menuList, Boolean ifLeafMenu) {
		List<DhtmlTreeNode> menuNodes = new ArrayList<DhtmlTreeNode>();
		if(menuList!=null && menuList.size()>0) {
			for(IMenu menu: menuList) {
				DhtmlTreeNode node = new DhtmlTreeNode();
				node.setId(menu.getId());
				node.setText(menu.getMenuName());
				if(menu.getMenuIcon()!=null && !"".equals(menu.getMenuIcon().trim())) {
					node.setIm0(menu.getMenuIcon().trim());
					node.setIm1(menu.getMenuIcon().trim());
					node.setIm2(menu.getMenuIcon().trim());
				} else {
					if(ifLeafMenu!=null && ifLeafMenu) {
						node.setIm0(this.cMenuIcon);
						node.setIm1(this.cMenuIcon);
						node.setIm2(this.cMenuIcon);
					} else {
						node.setIm0(this.pMenuIcon);
						node.setIm1(this.pMenuIcon);
						node.setIm2(this.pMenuIcon);
					}
				}
				//设置菜单节点链接
				node.getUserdata().add(new TreeUserData("menuAction", menu.getMenuAction())); 
				node.getItem().add(new DhtmlTreeNode("1", "1"));
				menuNodes.add(node);
			}
		}
		return menuNodes;
	}
	
	/**
	 * 通过菜单名称模糊查询
	 * @param menuName
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-24
	 */
	public List<IMenu> queryByMenuNameLike(String menuName) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		return iMenuDao.queryByMenuNameLike(menuName);
	}
	
	/**
	 * 菜单项新增或修改
	 * @param menu
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-24
	 */
	public ResponseMsg saveOrUpdateMenuItem(IMenu menu) throws Exception {
		//避免菜单节点关系发生变化
		if(menu.getParentID()==null || "".equals(menu.getParentID().trim())) {
			menu.setParentID(null);
		}
		menu.setMenuName(menu.getMenuName().trim());
		if(menu.getId()!=null && !"".equals(menu.getId())) { //菜单修改
			this.getiGenericDao().updateEntity(menu, menu.getId());
		} else { //菜单新增
			menu.setCreateTime(new Date());
			String menuID = this.getiGenericDao().saveEntity(menu);
			//构造菜单编号序列
			String menuIDSeq = null;
			if(menu.getParentID()!=null && !"".equals(menu.getParentID().trim())) {
				IMenu pMenu = this.getiGenericDao().queryEntityById(menu.getParentID());
				menuIDSeq = pMenu.getMenuIDSeq() + "." + menuID;
			} else {
				menuIDSeq = menuID;
			}
			menu.setMenuIDSeq(menuIDSeq);
			this.updateEntity(menu, menu.getId());
		}
		return ResponseMsg.getInstance(true, ""); 
	}
	
	/**
	 * 通过父菜单ID统计其子菜单的个数
	 * @param pMenuID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-24
	 */
	public int countChildrenByPMenuID(String pMenuID) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		return iMenuDao.countChildrenByPMenuID(pMenuID);
	}
	
	/**
	 * 通过角色唯一标识查询角色菜单授权树
	 * @param roleUID 角色唯一标识
	 * @param parentMenuID 树菜单的父节点，若为空表示查询顶层树节点
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-30
	 */
	public DhtmlTreeNode queryAuthorityTreeByRole(String roleUID, 
			String parentMenuID) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		//查询菜单节点
		List<IMenu> menuList = iMenuDao.queryChildMenuByParent(parentMenuID, null);
		//查询角色授权的菜单节点ID
		List<Object> menuIDList = iRoleMenuDao.queryMenuIDByRoleUID(roleUID);
		//构造授权菜单节点ID的格式化字符串
		String authorityMenuIDStr = "";
		if(menuIDList != null) {
			authorityMenuIDStr = menuIDList.toString();
		}
		//构造授权菜单树
		DhtmlTreeNode rootNode = new DhtmlTreeNode();
		if(parentMenuID!=null && !"".equals(parentMenuID.trim())) {
			IMenu rootMenu = this.getiGenericDao().queryEntityById(parentMenuID);
			rootNode.setId(rootMenu.getId());
			rootNode.setText(rootMenu.getMenuName());
			if(authorityMenuIDStr.indexOf(parentMenuID) >= 0) { //已授权菜单
				rootNode.setChecked("1"); //选中节点
			}
			rootNode.setOpen("1");
		} else {
			rootNode.setId("0");
			rootNode.setText("0");
			rootNode.setOpen("1");
		}
		if(menuList!=null && menuList.size()>0) {
			for(IMenu menu: menuList) {
				DhtmlTreeNode childNode = new DhtmlTreeNode();
				childNode.setId(menu.getId());
				childNode.setText(menu.getMenuName());
				if(authorityMenuIDStr.indexOf(menu.getId()) >= 0) { //已授权菜单
					childNode.setChecked("1"); //选中节点
				}
				childNode.setOpen("true");
				//设置虚拟子节点，便于树节点自动展开
				DhtmlTreeNode cVitualNode = new DhtmlTreeNode();
				cVitualNode.setId("1");
				cVitualNode.setText("1");
				childNode.getItem().add(cVitualNode);
				//组装树结构
				rootNode.getItem().add(childNode);
			}
		}
		return rootNode;
	}
	
	/**
	 * 保存角色菜单授权
	 * @param roleUID
	 * @param menuIDList 授权菜单列表
	 * 	格式：XXX,XXX,XXX
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-30
	 */
	public ResponseMsg saveRoleMenuAuthority(String roleUID, String menuIDList) throws Exception {
		//删除原有角色菜单关联信息
		this.iRoleMenuDao.deleteByRoleUID(roleUID);
		//保存角色菜单授权列表
		if(menuIDList!=null && !"".equals(menuIDList)) {
			String[] menuIDArray = menuIDList.trim().split("[,]");
			for(String menuID: menuIDArray) {
				IRoleMenu roleMenu = new IRoleMenu();
				roleMenu.setRoleUuid(roleUID);
				roleMenu.setMenuUuid(menuID);
				this.iRoleMenuDao.saveEntity(roleMenu);
			}
		}
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 通过系统访问的URL查询其对应的菜单位置
	 * @param visitUrl
	 * @return 返回从顶层菜单依次到底层菜单的列表
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-3-25
	 */
	public List<IMenu> queryMenuTraceByVisitUrl(String visitUrl) throws Exception {
		IMenuDao iMenuDao = (IMenuDao) this.getiGenericDao();
		IMenu urlMenu = iMenuDao.queryMenuByMenuAction(visitUrl);
		if(urlMenu != null) {
			return iMenuDao.queryMenuListBySeq(urlMenu.getMenuIDSeq());
		}
		return null;
	}

	/**
	 * @return the pMenuIcon
	 */
	public String getpMenuIcon() {
		return pMenuIcon;
	}

	/**
	 * @param pMenuIcon the pMenuIcon to set
	 */
	public void setpMenuIcon(String pMenuIcon) {
		this.pMenuIcon = pMenuIcon;
	}

	/**
	 * @return the cMenuIcon
	 */
	public String getcMenuIcon() {
		return cMenuIcon;
	}

	/**
	 * @param cMenuIcon the cMenuIcon to set
	 */
	public void setcMenuIcon(String cMenuIcon) {
		this.cMenuIcon = cMenuIcon;
	}

	/**
	 * @return the iRoleMenuDao
	 */
	public IRoleMenuDao getiRoleMenuDao() {
		return iRoleMenuDao;
	}

	/**
	 * @param iRoleMenuDao the iRoleMenuDao to set
	 */
	public void setiRoleMenuDao(IRoleMenuDao iRoleMenuDao) {
		this.iRoleMenuDao = iRoleMenuDao;
	}
	
}
